package edu.neu.cs6515.xml.converter;

import java.util.ArrayList;
import java.util.List;

import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

import edu.neu.cs6515.xml.False;
import edu.neu.cs6515.xml.Tile;
import edu.neu.cs6515.xml.w12.AdministratorResponses;
import edu.neu.cs6515.xml.w12.Rerack;
import edu.neu.cs6515.xml.w12.True;

public class AdministratorConverter implements Converter {

    @Override
    public boolean canConvert(final Class type) {
        return AdministratorResponses.class.equals(type);
    }

    @Override
    public void marshal(final Object source,
            final HierarchicalStreamWriter writer, final MarshallingContext context) {
        AdministratorResponses ar = (AdministratorResponses) source;
        List<Object> list = ar.getResponses();
        for (Object object : list) {
            if (object instanceof True) {
                writer.startNode("true");
                writer.endNode();
            } else if (object instanceof False) {
                writer.startNode("false");
                writer.endNode();
            } else if (object instanceof Tile) {
                Tile tile = (Tile) object;
                writer.startNode("tile");
                context.convertAnother(tile);
                writer.endNode();
            } else {
                Rerack rerack = (Rerack) object;
                writer.startNode("rerack");
                for (Tile tile : rerack.getTile()) {
                    writer.startNode("tile");
                    context.convertAnother(tile);
                    writer.endNode();
                }
                writer.endNode();
            }
        }
    }

    @Override
    public Object unmarshal(final HierarchicalStreamReader reader,
            final UnmarshallingContext context) {
        List<Object> list = new ArrayList<Object>();

        while (reader.hasMoreChildren()) {
            reader.moveDown();
            String nodeName = reader.getNodeName();
            if (nodeName.equals("true")) {
                list.add(new True());
            } else if (nodeName.equals("false")) {
                list.add(new False());
            } else if (nodeName.equals("tile")) {
                Tile tile = (Tile) new TileConverter().unmarshal(reader, context);
                list.add(tile);
            } else {
                List<Tile> tiles = new ArrayList<Tile>();
                while (reader.hasMoreChildren()) {
                    reader.moveDown();
                    Tile tile = (Tile) new TileConverter().unmarshal(reader, context);
                    tiles.add(tile);
                    reader.moveUp();
                }
                list.add(new Rerack(tiles));
            }
            reader.moveUp();
        }
        AdministratorResponses ar = new AdministratorResponses(list);
        return ar;
    }
}
